/*
 * Tutorial URL: http://docs.oracle.com/javase/tutorial/java/index.html
 * Swing URL: http://docs.oracle.com/javase/tutorial/uiswing/
 *
*/


class Vehicle {

	// CONSTRUCTORS
	public Vehicle(String make) {
		/* ABOUT CONSTRUCTORS
		* > Only if no constructor is provided, compiler provides a default no-argument constructor
		* > Constructor of the same type is invoked which is called at object creation
		* > However, only no-argument constructor of the base class is invoked on a child object creation
		* > Private constructors are not visible even to derived classes, so derived classes would not be able to create their objects if parent no-argument constructor is private.
		* > Constructors cannot be called explicitly as object methods. However, a derived class constructor can call parent class's n-argument constructor through special method named "super" => super(a, b, c);
		*/
		vehicle_make = new String(make);
	}

	enum vehicle_finish {

		//         (color_code, paint_type)
		AZURA_GRAY (0, 0),
		LOCAL_GRAY (0, 1);

		private final int color_code;
		private final int paint_type;

		vehicle_finish(int color_code, int paint_type) {
			this.color_code = color_code;
			this.paint_type = paint_type;
			return;
		}


		// Methods for the enum
		// ...
	}

	public Vehicle() {
		// This constructor is needed as we have a 1-argument constructor defined
		vehicle_make = "unknown";
		finishing = vehicle_finish.AZURA_GRAY;
	}


	// METHODS
	public insurance create_insurance() {
		
		insurance policy = this.new insurance();
		policy.insurance_present = true;

		return policy;
	}

	final public void print_make() {		// final keyword => method cannot be overridden in sub-class
	
		System.out.println(vehicle_make);
		return;
	}



	// MAIN
	public static void main (String[] args) {
		
		Vehicle car = new Vehicle("Maruti 800");
		insurance policy = car.create_insurance();

		car.print_make();

	}

	/* Member access levels:
	* Public: Accessible everywhere
	* Private: Only within the class
	* Protected: Accessible to all classes within the package, or sub-classes declared outside the package
	* <None>: Accessible to all classes within the package
	*/
	// MEMBERS
	private String vehicle_make;
	private vehicle_finish finishing;

	static final String vehicle_manufacturer = "maruti";	// final => constant

	// MEMBERS
	final class insurance {			
	

		/* Insurance policy is relevant only for the vehicle class.
		* Hence defined as a nested class
		*/

		// final => class cannot be further inherited
		// Opposed to it are "abstract" classes which cannot be instantiated. 
		// If a class contains an abstract method (method with implementation not provided), then the 
		// class also must be declared abstract.
		// Any sub-class of abstract class must define implementation of abstract methods, or should be 
		// itself an abstract class.
		
		// MEMBERS
		private boolean insurance_present;		// flag whether vehicle is insured
		private long policy_number;
		private int start_day;
		private int start_month;
		private int start_year;
		private int amount;
		private int duration;

		//METHODS
		// ...
	}
	
	/* No need to have an object of innter class defined in the outer class.
	 * Its upto the user to take insurance or not, but if taken, it has to be a part
	 * of some already created vehicle object
	*/
	//private insurance insurance_policy;

	// MEMBERS
	static class vendor_statistics {

		// Static class as it does not depend on any object instance.
		// An object of it is created as "new OuterClass.InnerClass"

		private int num_vehicles_created;
		private int num_vehicles_insured;
	}

}
